<template>
  <div class="comp-data-table">
    <simple-virtual-table
      v-if="tableColumns && tableColumns.length > 0"
      ref="virtualTable"
      key-field="_record_id_"
      column-key="name"
      :data-sources="tableData"
      :data-column="tableColumns"
      :height="height"
      :header-extra-width="70"
      @cell-click="onCellClick"
      @header-click="onTableHeaderClick"
      @context-menu="onContextmenu"
      @table-body-scroll="onTableScroll"
      @column-resize="onColumnResize"
    >
      <!-- 表头 -->
      <template #headerBefore>
        <!-- 增加序号列 -->
        <table-column
          key="xuhao"
          class="header-item data-cell"
          :width="70"
          fixed="left"
        >
          序号
        </table-column>
      </template>
      <!-- 表头数据列 -->
      <template #header="{column}">
        <span
          :class="checkColumnIsSelect(column) ? 'is-select-column' : ''"
          class="data-cell"
          >{{ column.name }}</span
        >
      </template>
      <!-- 序号列 -->
      <template #rowBefore="{index}">
        <table-column
          :width="70"
          class="data-cell"
          fixed="left"
          @click="($event) => onRowClick(index, $event)"
        >
          <span :index="index">{{ index + 1 }}</span>
        </table-column>
      </template>

      <!-- 数据 -->
      <template #cell="{column, row, index:$index}">
        <div
          :class="checkColumnIsSelect(column) ? 'is-select-column' : ''"
          style="height: 100%;"
        >
          <span
            :index="$index"
            :class="{
              'data-cell': true,
              'is-select-cell': checkCellIsSelect({ column, row, $index }),
            }"
          >
            <!-- 这一层用于关键字高亮 -->
            <span
              class="cell-content"
              :class="{
                null: [undefined, null, ''].includes(row[column.name]),
              }"
            >
            </span>
            <!-- 这一层用于触发刷选,请确保内容最后包含一个空格 -->
            <span
              class="cell-hight-light"
              :title="row[column.name]"
              @mouseup="
                onCellTextMouseup($event, { column, row, $index }, column)
              "
              >{{ row[column.name] }}
            </span>
          </span>
        </div>
      </template>
    </simple-virtual-table>
  </div>
</template>

<script lang="ts">
import { Vue, Component, Watch, Prop } from 'vue-property-decorator'
import GisStore, {
  IKeyValue,
  IColumn,
  CellInfo,
  SelectionInfo,
} from '@/store/modules/gis'
import { queryTableDetailApi } from '@/api/gis'
import { uniqBy } from 'lodash'
import SimpleVirtualTable from '@/components/simple-virtual-table/Table.vue'
import TableColumn from '@/components/simple-virtual-table/TableColumn.vue'
import { getLocalStorage, setLocalStorage } from '@/util/util'
import SelectionType from '@/util/selection-type'

// 定义为全局变量，减少赋值次数
// const NullValues = new Set([undefined, null, ''])

@Component({
  components: {
    SimpleVirtualTable,
    TableColumn,
  },
})
export default class GisDataTable extends Vue {
  @Prop({ default: false }) public isVisitor!: boolean // 是否访客模式
  private isLoading = false
  private totalPages: number = 0
  private timeMouseDown: number = 0
  private timeMouseUp: number = 0
  // 请求表数据参数
  private paginationParams = {
    curPage: 1,
    name: '_record_id_', // 如果没有字段，那就固定传 _record_id_
    pageSize: 50,
    filter: [],
  }
  /**
   * 当前数据对应的 表名 tableName
   * @private
   */
  private get tableName(): string {
    // 查询数据的表名取决于当前历史记录的表名，没有的话取  的表名
    return GisStore.selectLayer?.viewName
  }
  // 表格高度
  public get height() {
    const minHeight = 30
    return GisStore.tableHeight < minHeight ? minHeight : GisStore.tableHeight
  }
  /**
   * 预览 表数据的时候视为预览模式（禁止一些修改操作）
   */
  private get isPreviewMode(): boolean {
    return false
  }

  mounted() {
    const win = window as any
    const that = this
    const keyUp = function ($event: any) {
      if ($event.code === 'Escape') {
        console.log('Escape')
      }
    }

    const mouseDown = function () {
      that.timeMouseDown = new Date().valueOf()
    }
    const mouseUp = function () {
      that.timeMouseUp = new Date().valueOf()
    }

    win.document.addEventListener('mousedown', mouseDown)
    this.$once('hook:beforeDestroy', () => {
      win.document.removeEventListener('mousedown', mouseDown)
    })

    win.document.addEventListener('mouseup', mouseUp)
    this.$once('hook:beforeDestroy', () => {
      win.document.removeEventListener('mouseup', mouseUp)
    })

    win.document.addEventListener('keyup', keyUp)
    this.$once('hook:beforeDestroy', () => {
      win.document.removeEventListener('keyup', keyUp)
    })
  }

  /**
   * simple-virtual-table 右键 emit
   * @param columnData
   * @param event
   * @private
   */
  private onContextmenu(columnData: any, event: MouseEvent | null) {
    console.log(columnData, event, 'onContextmenu')
  }

  /**
   * 表明细数据
   * 全局搜索模式下返回搜索数据
   */
  public get tableData() {
    return uniqBy(GisStore.layerTableData, '_record_id_')
  }

  /** 表列 */
  public get tableColumns() {
    let gisColumnsWidthRecord: IKeyValue = {} // 存储的resize后的列宽度
    try {
      gisColumnsWidthRecord = JSON.parse(
        getLocalStorage('gisColumnsWidthRecord') || '{}'
      )
    } catch {
      gisColumnsWidthRecord = {}
    }
    GisStore.layerTableColumns.forEach((column: any) => {
      const key = `${this.tableName}-${column.name}`
      if (gisColumnsWidthRecord[key]) {
        column.width = gisColumnsWidthRecord[key]
      }
    })
    return GisStore.layerTableColumns
  }

  /**
   * 表名更新， 刷新数据
   * @param table
   */
  @Watch('tableName')
  public onTableName(table: any) {
    if (table) {
      this.initPaginationParamsAndStore()
      // 先清空数据
      GisStore.setLayerTableData({
        head: [],
        data: [],
      })
      this.getTableDataByLayer('refresh')
    }
  }

  // 需要更新数据的图层
  public get needUpdateTime() {
    return GisStore.needUpdateTime
  }

  public get updateLayerDataAfterGenerateNewField() {
    return GisStore.updateLayerDataAfterGenerateNewField
  }

  /**
   * 当前的图层数据有改动更新图标数据
   */
  @Watch('needUpdateTime')
  public updateLayerData() {
    // 只有当前显示的是改图层数据需要更新
    if (this.updateLayerDataAfterGenerateNewField.viewName === this.tableName) {
      this.initPaginationParamsAndStore()
      // 先清空数据
      GisStore.setLayerTableData({
        head: [],
        data: [],
      })
      this.getTableDataByLayer('refresh')
    }
  }

  /**
   * 初始化翻页数据
   * @private
   */
  private initPaginationParamsAndStore() {
    GisStore.setDataTableDetailLoading(true)
    GisStore.setColumnFilters([]) // 清空筛选项
    this.paginationParams = {
      ...this.paginationParams,
      curPage: 1,
      filter: [],
    }
    GisStore.clearDataTablePageInfo()
  }

  public get gisDataWidth(): number {
    return GisStore.gisDataWidth
  }

  @Watch('gisDataWidth')
  public onGisDataWidth() {
    this.resizeTableSize()
  }

  private resizeTableWidth() {
    const table = this.$refs.virtualTable as any
    if (table) {
      table.updateElWidth()
    }
  }

  private resizeTableSize() {
    const table = this.$refs.virtualTable as any
    if (table) {
      table.resize()
    }
  }

  /**
   * 获取当前节点的具体信息：列字段、表明细等
   * refresh: 刷新表格数据
   * combine: 翻页追加
   */
  async getTableDataByLayer(flag: 'refresh' | 'combine' = 'combine') {
    if (!this.tableName) {
      return
    }
    const response = await queryTableDetailApi({
      data: {
        ...this.paginationParams,
        table: this.tableName,
        taskId: -7,
      },
    })
    this.isLoading = false
    GisStore.setDataTableDetailLoading(false)
    const result = response.data.result || {}
    this.totalPages = result.page ? result.page.totalPages : 0
    GisStore.setTotalPages(this.totalPages)
    GisStore.setTableDataCount(result.page ? result.page.totalElements : 0)
    // 翻页追加
    if (flag === 'combine') {
      GisStore.setLayerTableData({
        head: GisStore.layerTableColumns,
        data: this.tableData.concat(result.data || []),
        mode: 'detail',
      })
    } else {
      const head: any[] = result.head.filter(
        (column: any) =>
          column.name !== 'geom' &&
          column.name !== 'geom_4326' &&
          column.name !== 'geom_transform'
      )
      GisStore.setLayerTableData({
        head: head || [],
        data: result.data || [], // 刷新数据
        mode: 'all', // detail:只是table detail更新，all: header和detail都更新
      })
    }
    GisStore.setTableCurPage(this.paginationParams.curPage)
  }

  /**
   * 表格内容滚动 emit
   */
  private onTableScroll(data: any) {
    if (this.isPreviewMode) {
      return
    }
    const { scrollToBottom } = data // 是否滚动到底部
    //  统一createColumnView里的table curPage
    if (this.paginationParams.curPage < GisStore.tableCurPage) {
      this.paginationParams.curPage = GisStore.tableCurPage
    }
    if (
      scrollToBottom &&
      this.paginationParams.curPage < this.totalPages &&
      !this.isLoading &&
      GisStore.tableCurPage < this.totalPages
    ) {
      this.isLoading = true
      this.paginationParams = {
        ...this.paginationParams,
        curPage: this.paginationParams.curPage + 1,
      }
      this.getTableDataByLayer()
    }
  }

  /**
   * 单元格鼠标抬起 刷选操作
   * @param event
   * @param scope
   * @param column
   */
  public onCellTextMouseup(event: any, scope: any, column: IColumn) {
    if (this.isPreviewMode) {
      this.clearSelections()
      return
    }
    setTimeout(() => {
      if (event.target && event.target instanceof HTMLElement) {
        const selection = (window as any).getSelection()
        if (
          selection.baseNode &&
          selection.focusOffset >= 0 &&
          selection.baseOffset >= 0 &&
          selection.focusOffset - selection.baseOffset !== 0
        ) {
          // 这里有可能从左向右或者从右到左刷选
          const selectData = (selection.baseNode.data as string).slice(
            Math.min(selection.baseOffset, selection.focusOffset),
            Math.max(selection.baseOffset, selection.focusOffset)
          )
          if (selectData) {
            // 这里要确保从左到右刷选|从右到左刷选后startIndex 都比 endIndex小
            const startIndex = Math.min(
              selection.baseOffset,
              selection.focusOffset
            )
            const endIndex = Math.max(
              selection.baseOffset,
              selection.focusOffset
            )
            let startWithWord = ''
            // todo selectData.indexOf(' ') === -1 这个条件待考虑
            /* eslint-disable */
            if (
              startIndex > 1 &&
              selectData.indexOf(' ') === -1 &&
              selection.baseNode.data[startIndex - 1] === ' '
            ) {
              const prefixArray: Array<string> = `${selection.baseNode.data}`
                .slice(0, startIndex - 1)
                .split(' ')
              // 这里有个特殊情况：  在 'aa  bbcc' 字符串中，刷选bb后split出来最后 startWithWord 还是空字符串，这种情况暂时排除在 startWithWord之外
              startWithWord = prefixArray[prefixArray.length - 1]
            }
            let endWithWord = ''
            if (
              endIndex < selection.baseNode.data.length - 2 &&
              selection.baseNode.data[endIndex] === ' '
            ) {
              // 这里特殊情况同上
              const subArray: Array<string> = `${selection.baseNode.data}`
                .slice(endIndex + 1, (selection.baseNode.data as string).length)
                .split(' ')
              endWithWord = subArray[0] as string
            }
            let wordPos = 0
            // 选中字符作为单词((前面有空格， 或者在首部)并且 (后面有空格或刷选到末尾))
            if (
              (selection.baseNode.data[startIndex - 1] === ' ' ||
                startIndex === 0) &&
              (selection.baseNode.data[endIndex] === ' ' ||
                (selection.baseNode.data as string).length === endIndex)
            ) {
              if (startIndex === 0) {
                wordPos = 1
              } else {
                const prefixArray: Array<string> = `${selection.baseNode.data}`
                  .slice(0, startIndex - 1)
                  .split(' ')
                wordPos = prefixArray.length + 1
              }
            }
            // 刷选信息
            const selectionInfo: SelectionInfo = {
              startIndex, // 起始位
              endIndex, // 结束位置
              isStartWith: startIndex === 0, // 是否符合以XXX开头的条件
              isEndWidth: endIndex === selection.baseNode.data.length - 1, // 是否符合以XXX结尾的条件
              // 是否符合单词位置推荐的条件（前后有空格），这里位置指的是单词位置 todo 这里还要判断是英文？不好界定。待后续补充
              isWordPos:
                /* eslint-disable */
                selectData.indexOf(' ') === -1 && // 本身不能包含空格
                ((startIndex === 0 &&
                  selection.baseNode.data[endIndex] === ' ') || // 在最前面
                (selection.baseNode.data[startIndex - 1] === ' ' &&
                  selection.baseNode.data[endIndex] === ' ') || // 单词在中间
                  (selection.baseNode.data[startIndex - 1] === ' ' &&
                    endIndex === selection.baseNode.data.length - 1)), // 单词在末尾
              wordPos, // 单词位置
              isSelectionPos: true, // 是否符合选中位置一样的规则,这里位置指的是索引位置
              isSameSelection: true,
              isStartWithWord: startWithWord.length > 0, // 是否符合刷选内容前面为xx单词的规则，刷选内容在最前面且后面有空格
              startWithWord, // 前置单词
              isEndWithWord: endWithWord.length > 0, // 是否符合刷选内容后面为xx单词的规则，刷选内容在最后面且前面有空格
              endWithWord, // 后置单词
              _record_id_: scope.row._record_id_,
              rowIndex: scope.$index,
              columnName: column.name,
              selection: selectData,
              columnDesc: column.desc, // 当前列（字段）类型
              fullValue: scope.row[column.name], // 刷选的当前值（完整）
            }

            // 以下是处理刷选多个单元格的问题
            const selectionInfoOld = GisStore.tableSelectionInfo
              ? { ...GisStore.tableSelectionInfo }
              : null
            // 确保新刷选的单元格在同一列
            if (
              this.isCtrlSelect(event) &&
              selectionInfoOld &&
              selectionInfoOld.columnName === selectionInfo.columnName
            ) {
              let multipleSelectionInfo = selectionInfoOld.multipleSelectionInfo
              if (!multipleSelectionInfo) {
                // 如果没有多选选择信息
                multipleSelectionInfo = {
                  // 这里包含一个隐式信息刷选的有肯能就是已刷选的那个单元格
                  [`${selectionInfoOld._record_id_}_${selectionInfoOld.rowIndex}`]: selectionInfoOld,
                  [`${selectionInfo._record_id_}_${selectionInfo.rowIndex}`]: selectionInfo,
                }
              } else {
                multipleSelectionInfo[
                  `${selectionInfo._record_id_}_${selectionInfo.rowIndex}`
                ] = selectionInfo
              }
              const selectionInfoArray = Object.values(multipleSelectionInfo) // 选中信息
              const isMultiple = selectionInfoArray.length > 1
              if (!isMultiple) {
                this.clearTableSelectCells()
                this.clearTableColumns()
                this.clearTableSelection()
                GisStore.setTableSelectionInfo(selectionInfo)
                GisStore.setTableSelectionType(SelectionType.selection)
                this.$nextTick(() => {
                  this.clearWindowSelection()
                })
              } else {
                const selectionInfoSet = {
                  isMultiple: true, // 多选模式
                  startIndex: selectionInfo.startIndex,
                  endIndex: selectionInfo.endIndex,
                  isStartWith: selectionInfoArray.every(
                    (item: any) =>
                      item.isStartWith && item.selection === selectData
                  ), // 所有选中都是以xxx开头
                  isEndWidth: selectionInfoArray.every(
                    (item: any) =>
                      item.isEndWidth && item.selection === selectData
                  ), // 所有选中都是以xxx结尾
                  isWordPos: selectionInfoArray.every(
                    (item: any) => item.isWordPos && item.wordPos === wordPos
                  ), // 单词位置模式？
                  wordPos, // 单词位置
                  isSelectionPos: selectionInfoArray.every(
                    (item: any) =>
                      item.startIndex === startIndex &&
                      item.startIndex === endIndex
                  ), // 选中索引一致？
                  isStartWithWord: selectionInfoArray.every(
                    (item: any) =>
                      item.isStartWithWord &&
                      item.startWithWord === startWithWord
                  ), // 都以xxx单词前置
                  startWithWord, // 前置单词
                  isEndWithWord: selectionInfoArray.every(
                    (item: any) =>
                      item.isEndWithWord && item.endWithWord === endWithWord
                  ), // 都以xxx单词后置
                  endWithWord, // 后置单词
                  _record_id_: scope.row._record_id_,
                  rowIndex: scope.$index,
                  columnName: column.name,
                  selection: selectData,
                  isSameSelection: selectionInfoArray.every(
                    (item: any) => item.selection === selectData
                  ), // 所有选中一致？
                  isSamePos: selectionInfoArray.every(
                    (item: any) =>
                      item.startIndex === startIndex &&
                      item.endIndex === endIndex
                  ), // 所有选中位置一致？
                  rowIndexArray: selectionInfoArray.reduce(
                    (rec: any, item: any) => {
                      // 选中行索引集合
                      rec.push(item.rowIndex)
                      return rec
                    },
                    [] as Array<number>
                  ),
                  _record_id_Array: selectionInfoArray.reduce(
                    (rec: any, item: any) => {
                      // 选中行记录号集合
                      rec.push(item._record_id_)
                      return rec
                    },
                    [] as Array<string>
                  ),
                  multipleSelectionInfo,
                }
                this.clearTableSelectCells()
                this.clearTableColumns()
                this.clearTableSelection()
                GisStore.setTableSelectionInfo(selectionInfoSet)
                GisStore.setTableSelectionType(SelectionType.selection)
                this.$nextTick(() => {
                  this.clearWindowSelection()
                })
              }
            } else {
              this.clearTableSelectCells()
              this.clearTableColumns()
              this.clearTableSelection()
              GisStore.setTableSelectionInfo(selectionInfo)
              GisStore.setTableSelectionType(SelectionType.selection)
              this.$nextTick(() => {
                this.clearWindowSelection()
              })
            }
          } else {
            GisStore.setTableSelectionInfo(null)
            if (GisStore.tableSelectionType === SelectionType.selection) {
              GisStore.setTableSelectionType(SelectionType.none)
            }
          }
        }
      }
    }, 10)
  }

  /**
   * 表头点击事件 emit
   */
  private onTableHeaderClick(columnData: any, event: any) {
    if (this.timeMouseUp - this.timeMouseDown > 300 || this.isPreviewMode) {
      return
    }
    // 点击的列
    const columnClicked = this.tableColumns.find((column: any) => {
      return column.name === columnData.name
    })
    if (columnClicked) {
      this.toggleSelectionChange([])
      GisStore.setTableSelectRowNumbers([])
      this.clearTableSelectCells()
      // ctrl 多选
      if (this.isCtrlSelect(event)) {
        GisStore.toggleSelectedColumn(columnClicked)
        GisStore.toggleTableSelectColumn(columnClicked)
        // 这里可能导致没有任何列被选中
        if (GisStore.tableSelectColumns.length === 0) {
          GisStore.setTableSelectionType(SelectionType.none)
        } else {
          GisStore.setTableSelectionType(SelectionType.columns)
        }
      } else {
        GisStore.setSelectedColumns([columnClicked])
        GisStore.setTableSelectColumns([columnClicked])
      }
      if (GisStore.tableSelectColumns.length > 0) {
        GisStore.setTableSelectionType(SelectionType.columns)
      } else {
        GisStore.setTableSelectionType(SelectionType.none)
      }
    }
  }

  /**
   * 序号行点击事件 emit
   */
  public onRowClick(index: number, event: MouseEvent) {
    GisStore.setTableSelectColumns([])
    GisStore.setSelectedColumns([])
    const dom = event.currentTarget // cell.querySelector('.data-cell')
    const row = this.tableData[index]
    if (dom) {
      // const index = dom.getAttribute('index') as string
      // Ctrl 多选
      if (this.isCtrlSelect(event)) {
        GisStore.toggleTableSelectData(row)
        GisStore.toggleTableSelectRowNumber(index)
        // 这里可能导致没有任何行被选中
        if (GisStore.tableSelectRowDatas.length === 0) {
          GisStore.setTableSelectionType(SelectionType.none)
        }
      } else {
        GisStore.setTableSelectRowNumbers([index])
        GisStore.setTableSelectRowDatas([row])
      }

      if (GisStore.tableSelectRowDatas.length > 0) {
        GisStore.setTableSelectionType(SelectionType.rows)
      }
    }
  }

  /**
   * 单元格点击事件 emit
   */
  public onCellClick(row: any, column: any, cell: HTMLElement, event: any) {
    if (this.isPreviewMode) {
      return
    }
    if (column.name === '$$$序号$$$') {
      console.log('序号')
    } else {
      const selection = (window as any).getSelection()
      if (
        ['varchar', 'text'].includes(column.desc) &&
        selection.baseNode &&
        selection.focusOffset &&
        selection.baseOffset >= 0 &&
        Math.abs(selection.focusOffset - selection.baseOffset) > 0
      ) {
        // 有刷选就直接屏蔽
        return
      }
      const dom = cell.querySelector('.data-cell')
      if (dom) {
        const index = dom.getAttribute('index') as string
        this.clearTableSelection()
        this.clearTableColumns()
        const cellData: CellInfo = {
          rowIndex: Number.parseInt(index, 10),
          columnName: column.name,
          _record_id_: row._record_id_ || '',
          cellValue: row[column.name],
        }
        // 多选
        if (event.ctrlKey) {
          GisStore.toggleTableSelectCell(cellData)
        } else {
          GisStore.setTableSelectCells([cellData])
        }

        if (GisStore.tableSelectCells.length > 0) {
          GisStore.setTableSelectionType(SelectionType.cells)
        } else {
          GisStore.setTableSelectionType(SelectionType.none)
        }
      }
    }
  }

  /**
   * 设置数据选中状态 (行)
   */
  private toggleSelectionChange(rows: Array<any>, isSelect: Boolean = false) {
    if (this.tableColumns && this.tableColumns.length > 0) {
      //  确保表格存在数据时执行
      if (rows.length > 0) {
        if (isSelect) {
          ;(this.$refs.virtualTable as any).toggleRowSelection(
            rows.map((row) => ({ row, selected: true }))
          )
        } else {
          ;(this.$refs.virtualTable as any).toggleRowSelection(
            rows.map((row) => ({ row }))
          )
        }
      } else {
        ;(this.$refs.virtualTable as any).clearSelection()
      }
    }
  }

  /**
   * 表格选择的列
   */
  private get selectColumns() {
    return GisStore.tableSelectColumns
  }

  /**
   * 选择的行数据
   * @private
   */
  private get selectRowData() {
    return GisStore.tableSelectRowDatas
  }

  /**
   * 选择的行数据发生变化
   * @param newValue
   * @private
   */
  @Watch('selectRowData', { immediate: true, deep: true })
  private onSelectRowDataChange(newValue: Array<any>) {
    this.clearTableSelection()
    this.clearTableSelectCells()
    this.$nextTick(() => {
      this.toggleSelectionChange(newValue, true)
    })
  }

  /**
   * 清空表格选择的单元格
   * @private
   */
  private clearTableSelectCells() {
    GisStore.setTableSelectCells([])
  }

  /**
   * 清空表格的选择
   * @private
   */
  private clearTableSelection() {
    const table = this.$refs.virtualTable as any
    if (table) {
      table.clearSelection()
    }
  }

  /**
   * 清空 表格选择的列， 和卡片列选择的列
   * @private
   */
  private clearTableColumns() {
    GisStore.setTableSelectColumns([])
    GisStore.setSelectedColumns([])
  }

  /**
   * clear seletions
   * @private
   */
  private clearSelections() {
    this.clearWindowSelection()
    GisStore.setTableSelectionInfo(null)
  }

  private clearWindowSelection() {
    const document = (window as any).document as any
    if (window.getSelection) {
      // 获取选中
      const selection = window.getSelection()
      // 清除选中
      if (selection) {
        selection.removeAllRanges()
      }
    } else if (document.selection && document.selection.empty) {
      // 兼容 IE8 以下，但 IE9+ 以上同样可用
      document.selection.empty()
      // 或使用 clear() 方法
      // document.selection.clear();
    }
  }

  /**
   * 列是否被选中 （high-light）
   * @param column
   * @private
   */
  private checkColumnIsSelect(column: IColumn): boolean {
    return (
      this.selectColumns.findIndex((columnItem) => {
        return columnItem.name === column.name
      }) > -1
    )
  }

  /**
   * 单元格是否被选中 （high-light）
   * @param scope
   * @private
   */
  private checkCellIsSelect(scope: any) {
    return GisStore.tableSelectCells.find((cellInfo: CellInfo) => {
      return (
        cellInfo.rowIndex === scope.$index &&
        cellInfo.columnName === scope.column.name
      )
    })
  }

  /**
   * 调整列宽并记录到浏览器的存储中
   */
  private onColumnResize(column: IColumn, width: number) {
    let gisColumnsWidthRecord: IKeyValue = {}
    try {
      gisColumnsWidthRecord = JSON.parse(
        getLocalStorage('gisColumnsWidthRecord') || '{}'
      )
    } catch {
      gisColumnsWidthRecord = {}
    }
    gisColumnsWidthRecord[`${this.tableName}-${column.name}`] = width // 根据 '表名-列名' 标识来记录
    setLocalStorage(
      'gisColumnsWidthRecord',
      JSON.stringify(gisColumnsWidthRecord)
    )
  }

  // is mac
  private get isMac() {
    const { userAgent } = window.navigator
    return userAgent.includes('Mac OS X')
  }

  // ctrl 多选
  private isCtrlSelect(event: MouseEvent) {
    if (this.isMac) {
      return event.metaKey
    }
    return event.ctrlKey
  }
}
</script>

<style lang="less" scoped>
.comp-data-table {
  background-color: #fafafc;
  padding-left: 12px;
  padding-top: 5px;

  /deep/ .plTableBox .el-table--mini td,
  /deep/ .plTableBox .el-table td {
    padding: 0;
  }

  /deep/ .plTableBox tr {
    th .cell {
      white-space: nowrap;
    }

    .cell {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }
  }

  /deep/ .plTableBox td {
    .cell {
      padding-left: 0 !important;
      padding-right: 0 !important;

      .data-index {
        padding-left: 8px;
      }

      .data-cell .cell-content {
        padding-left: 8px;
        padding-right: 8px;
      }
    }
  }

  /deep/ .plTableBox .el-table td {
    background: transparent;
  }

  /deep/ .plTableBox .el-table tr {
    background: #fafafc;

    &:nth-child(2n) {
      background: #f3f3f3;
    }
  }

  /deep/ .plTableBox .has-gutter {
    .is-select-column {
      background: rgb(238, 239, 252) !important;
    }

    th .cell {
      color: #5d637e;
      font-family: 'Microsoft YaHei', '微软雅黑', 'Arial Narrow', Arial,
        sans-serif;
      font-size: 12px;
    }
  }

  /deep/ .is-select-column {
    background: rgb(238, 239, 252) !important;

    .is-set-select-cell {
      background: rgba(103, 113, 252, 0.1);
    }
  }

  /deep/ .select-tr {
    background: rgb(238, 239, 252) !important;
  }

  /deep/ .select-tr .table-cell {
    background: transparent !important;
  }

  /deep/ .current-row {
    background: transparent;

    td:not(.is-select-column) {
      background: transparent !important;
    }

    .is-select-column {
      background: rgb(238, 239, 252) !important;
    }
  }

  /deep/ .select-tr.current-row {
    background: rgb(238, 239, 252) !important;

    td {
      background: transparent !important;
    }
  }

  /deep/ .is-select-cell {
    background: rgb(238, 239, 252) !important;
  }

  /deep/ .data-cell {
    display: block;
    height: 100%;
    padding: 6px 10px;
    position: relative;
    text-overflow: ellipsis;
    white-space: nowrap;
    width: 100%;

    .cell-content {
      display: block;
      height: auto;
      overflow: hidden;
      pointer-events: none;
      position: relative;
      text-overflow: ellipsis;

      &.null {
        color: transparent;
      }
    }

    .cell-common {
      display: block;
      height: auto;
      overflow: hidden;
      padding: 0 8px;
      pointer-events: all;
      position: relative;
      text-overflow: ellipsis;
      user-select: text;
    }

    .cell-hight-light {
      bottom: 0;
      left: 0;
      overflow: hidden;
      padding: 6px 10px;
      pointer-events: all;
      position: absolute;
      right: 0;
      text-overflow: ellipsis;
      top: 0;
      user-select: text;
      white-space: nowrap;
      z-index: 0;
    }

    // &::before,
    // &::after {
    //   background: inherit;
    //   content: ' ';
    //   height: 100%;
    //   left: -10px;
    //   position: absolute;
    //   top: 0;
    //   width: 10px;
    // }

    // &::after {
    //   left: auto;
    //   right: -10px;
    // }
  }

  /deep/ .selection-cell {
    left: 0;
    overflow: hidden;
    pointer-events: none;
    position: absolute;
    text-overflow: ellipsis;
    top: 0;
    user-select: none;
    width: 100%;
    z-index: 1;
  }

  /deep/ .select-word {
    position: relative;

    &::after {
      background: rgba(103, 113, 252, 0.2);
      content: ' ';
      height: 32px;
      left: 0;
      pointer-events: none;
      position: absolute;
      top: -10px;
      width: 100%;
      z-index: 1;
    }
  }
  // 全局搜索关键字高亮
  /deep/ .global-search-word {
    background: rgba(250, 210, 77, 0.9);
    position: relative;
  }

  /deep/ .is-set-select-row,
  /deep/ .is-set-select-cell {
    background: rgb(238, 239, 252);
  }
}

.contextmenu-box {
  width: 110px;
  z-index: 10;
}
</style>
